﻿using DA.AnimGraph;
using OdinSerializer;
using System.Collections.Generic;

namespace DA.AnimGraph.Editor {

    internal class AGANode_AxisBlend1D : AGANode_BlendBase {

        public override AGANodeModelBase modelProperty { set => model = (AGANodeModel_AxisBlend1D)value; get => model; }
        [OdinSerialize] AGANodeModel_AxisBlend1D model;
        public AGANode_AxisBlend1D(AGANodeModelBase model) : base(model) {
            var portUuid = AUIDGenerator.Gen();
            inputChildren.Add(portUuid);
            inputNames.Add("port 0");
            var newPortPosition = new AGAFieldModel_AxisBlend1DPort(portUuid);
            newPortPosition.position.Add(0);
            this.model.portsPositions.Add(newPortPosition);
        }
        public override int Publish(List<PublishNode> outNodes, AGAPublisher.PublishContext context) {
            var pNode = new AxisBlend1DPNode();
            pNode.uuid = uuid;
            pNode.data = model.Publish(context);
            var index = outNodes.Count;
            outNodes.Add(pNode);

            pNode.inputChildren = new int[inputChildren.Count];
            for (int i = 0; i < inputChildren.Count; i++) {
                var childUuid = inputChildren[i];
                var childNode = context.subGraph.FindNextNodeInstance(uuid, childUuid) as AGANode_FunctionBase;
                if (childNode != null) pNode.inputChildren[i] = AGAPublisher.ExportNode(childNode, outNodes, context);
                else pNode.inputChildren[i] = -1;
            }

            PublishPerks(pNode, context);
            return index;
        }
    }

    [ModelOf(typeof(AGANode_AxisBlend1D))]
    internal class AGANodeModel_AxisBlend1D : AGANodeModelBase {

        public AGAFieldModel_FloatLink inputPosition = new();
        public List<AGAFieldModel_AxisBlend1DPort> portsPositions = new();

        public AxisBlend1DNode.SetupData Publish(AGAPublisher.PublishContext context) {

            int portCount = portsPositions.Count; //输入端口数量
            int positionCount = 0; //坐标数量，因为一个端口可能对应多个坐标，所以 positionCount >= portCount
            var ports = new List<(float, int)>(portCount); // (坐标, 对应的端口id)。长度为positionCount，但此时还不知道所以先用portCount
            for (int i = 0; i < portsPositions.Count; i++) {
                positionCount += portsPositions[i].position.Count;
                for (int j = 0; j < portsPositions[i].position.Count; j++) {
                    ports.Add((portsPositions[i].position[j], i));
                }
            }
            ports.Sort((l, r) => {
                return l.Item1.CompareTo(r.Item1);
            });

            int[] portIds = new int[positionCount];
            float[] portPos = new float[positionCount];
            for (int i = 0; i < positionCount; i++) {
                portIds[i] = ports[i].Item2;
                portPos[i] = ports[i].Item1;
            }

            var result = new AxisBlend1DNode.SetupData() {
                inputDesc = inputPosition.Publish(context),
                portIds = portIds,
                portPos = portPos,
            };
            return result;
        }
        // public struct SetupData : INodeSetupData {
        //     public FloatLinkDesc inputDesc;
        //     public int[] portIds; // 长度和clipsPos一样，内容是输入端口的序号，将pos映射到输入端口序号
        //     public float[] portPos; // 要求已经从小到大排好
        // }
    }

}
